#ifndef __MUTEXFILE_H__
#define __MUTEXFILE_H__

/**
 * @file mutexqueue.h
 * @brief Librairie de liste chainée avec mutex pour la gestion de fichiers.
 * @author Florian.B
 * @version 0.1
 * @date 6 avril 2012
 *
 * Librairie fournissant un gestionnaire de liste chainée avec des mutex pour pallier au problème lecteur rédacteur.
 *
 */

#include <pthread.h>
#include "../tools/list.h"
#include "socketfile.h"

/**
 * @struct MutexFile
 * @brief Objet MutexFile
 *
 * MutexFile est un petit objet qui permet de gerer une liste en gérant les accès concurrents de lecteur rédacteur.
 */
typedef struct _MutexFile
{
  List listFileUse; /*!< La liste contenant les donnnées associés à la socket. */
  pthread_mutex_t mutexWrite; /*!< Le mutex d'ajout d'une entrée à la fin de la liste. */
  pthread_cond_t condWrite; /*!< La condition d'attente d'écriture sur la liste. */
  pthread_mutex_t mutexRead; /*!< Le mutex de lecture sur la liste */
  pthread_cond_t condRead; /*!< La condition d'attente de lecture sur la liste. */
  pthread_mutex_t mutexEquity; /*!< Le mutex d'équité */
  int cptRead; /*!< Compteur sur les lecteurs */
}MutexFile;

/**
 * @enum MutexFileReturn
 * @brief Constantes de retour.
 *
 * MutexFileReturn est une série de constatnes prédéfinie pour diverses futures fonctions de l'objet MutexFile.
 */
typedef enum
  {
    MUTEXFILE_SUCCESS, /*!< Succès. */
    MUTEXFILE_ERR, /*!< Erreur. */
    MUTEXFILE_INSIDE, /*!< L'élément est à l'intérieur de la liste */
    MUTEXFILE_NOT_INSIDE, /*!< L'élément n'est pas à l'intérieur de la liste */
    MUTEXFILE_NB_RET /*!< Nombre total de constantes de retour. */
  }MutexFileReturn;

/**
 * @fn void initializes_MutexFile(MutexFile *mutexFile)
 * @brief Fonction d'initialisation d'un mutexFile.
 *
 * @param[in,out] mutexFile Mutex à initialiser.
 */
void initialize_MutexFile(MutexFile *mutexFile);

/**
 * @fn void testament_Mutex(Mutex *mutex)
 * @brief Fonction de libération d'un mutexFile.
 *
 * @param[in,out] mutexFile MutexFile qui sera libérée.
 */
void testament_MutexFile(MutexFile *mutexFile);

/**
 * @fn MutexFileReturn tryInsert_MutexFile(MutexFile *mutexFile, const Element element);
 * @brief Fonction d'ajout (si l'élément n'existe pas) en queue dans la liste.
 *
 * @param[in,out] mutexFile Le MutexFile qui prendra l'élément.
 * @param element L'élément à insérer.
 * @return MUTEXFILE_SUCCESS pour le succès, MUTEXFILE_INSIDE si l'élément est déjà dans la liste et MUTEXFILE_ERR en cas d'erreur.
 */
MutexFileReturn tryInsert_MutexFile(MutexFile *mutexFile, const Element element);

/**
 * @fn MutexFileReturn isInside_MutexFile(MutexFile *mutexFile, const Element element)
 * @brief Fonction qui recherche un élément dans la liste.
 *
 * @param[in,out] mutexFile Le mutexFile de travail.
 * @param element L'élément recherché.
 * @return MUTEXFILE_INSIDE si l'élément rechercher est dans la liste et MUTEXFILE_NOT_INSIDE si l'élément n'y est pas.
 */
MutexFileReturn isInside_MutexFile(MutexFile *mutexFile, const Element element);

/**
 * @fn MutexFileReturn delete_MutexFile(MutexFile *mutexFile, const Element element)
 * @brief Fonction qui supprime l'élément de la liste.
 * 
 * @param[in,out] mutexFile Le mutexFile de travail.
 * @param element L'élément à supprimer.
 * @return MUTEXFILE_SUCCESS si l'élément est supprimé de la liste, MUTEXFILE_NOT_INSIDE si l'élément n'est pas dans la liste et MUTEXFILE_ERR si l'élément n'est pas supprimé.
 */
MutexFileReturn delete_MutexFile(MutexFile *mutexFile, const Element element);

#endif
